package jp.co.brilliantservice.app.openar.view;

import java.util.Collections;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import jp.co.brilliantservice.app.openar.data.ARObject;
import jp.co.brilliantservice.app.openar.data.ScreenItem;
import jp.co.brilliantservice.app.openar.util.Calculate;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.location.Location;
import android.util.AttributeSet;
import android.view.View;

public class DataView extends View {
	private static Paint mBasePaint = null;
	private static Paint mFramePaint = null;
	private static Paint mTextPaint = null;
	private boolean mIsInit = false;
	public List<ARObject> mItems = null;
	RectF frameRect = new RectF(0,0,0,0);
	private int mRange;
	private double mLatitude;
	private double mLongitude;

	public DataView(Context context) {
		super(context);
		init();
	}

	public DataView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		if (!mIsInit) {
			mItems = new ArrayList<ARObject>();
			mBasePaint = new Paint();
			mBasePaint.setARGB(200, 75, 75, 155);
			mFramePaint = new Paint();
			mFramePaint.setARGB(200, 55, 55, 135);
			mFramePaint.setAntiAlias(true);
			mFramePaint.setStyle(Style.STROKE);
			mFramePaint.setStrokeWidth(2);
			mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
			mTextPaint.setColor(Color.WHITE);
			mTextPaint.setTextSize(14);
			mIsInit = true;
		}
	}

	public void addItem(ARObject item) {
		if (mItems == null) {
			mItems = new ArrayList<ARObject>();
		}
		synchronized (mItems) {
			mItems.add(item);
		}
		Calculate.setLocation(mItems, mLatitude, mLongitude);
		sortData();
	}

	public void addItems(List<ARObject> items) {
		if (mItems == null) {
			mItems = new ArrayList<ARObject>();
		}
		synchronized (mItems) {
			for (ARObject item : items) {
				mItems.add(item);
			}
		}
		Calculate.setLocation(mItems, mLatitude, mLongitude);
		sortData();
	}

	public void setItems(List<ARObject> items) {
		synchronized (mItems) {
			mItems.clear();
			mItems.addAll(items);
		}
		Calculate.setLocation(mItems, mLatitude, mLongitude);
		sortData();
	}

	public void hideItem(String uid) {
		if (mItems == null) {
			return;
		}
		for (int i=0; i<mItems.size(); i++) {
			if (mItems.get(i).mUid.compareTo(uid)==0) {
				mItems.get(i).setDisplay(ScreenItem.HIDE);
				break;
			}
		}
	}

	public void displayItem(String uid) {
		if (mItems == null) {
			return;
		}
		for (int i=0; i<mItems.size(); i++) {
			if (mItems.get(i).mUid.compareTo(uid)==0) {
				mItems.get(i).setDisplay(ScreenItem.DISPLAY);
				break;
			}
		}
	}

	public void clearAllItems() {
		if (mItems == null) {
			return;
		}
		synchronized (mItems) {
			for (ARObject item : mItems) {
			item.clearIcon();
			}
			mItems.clear();
		}
	}

	private void sortData() {
		synchronized (mItems) {
			Collections.sort(mItems, new Comparator<ARObject>() {
				public int compare(ARObject object1, ARObject object2) {
					if (object1.mDistance > object2.mDistance) {
						return -1;
					} else if (object1.mDistance < object2.mDistance) {
						return 1;
					}
					return 0;
				}
			});
		}
	}

	public void setRange(int range) {
		mRange = range;
		Calculate.setRange(mItems, range);
	}

	public void setViewSize(int width, int height) {
		Calculate.setViewSize(width, height);
	}

	public void updateLocation(Location location) {
		updateLocation(location.getLatitude(), location.getLongitude());
	}

	public synchronized void updateLocation(double latitude, double longitude) {
		mLatitude = latitude;
		mLongitude = longitude;
		Calculate.setLocation(mItems, latitude, longitude);
		sortData();
	}

	public void updateOrientation(double azimuth, double pitch, double roll) {
		Calculate.updateScreenPoints(mItems, pitch, azimuth);
	}

	@Override
	protected void dispatchDraw(Canvas canvas) {
		String text = null;
//		Log.e("dispatchDraw","dispatchDrawdispatchDrawdispatchDraw");
		if (mItems!=null) {
			synchronized (mItems) {
				for (ARObject item : mItems) {
					if (!item.isDisplay() || item.mDistance > mRange) {
						continue;
					}
					if (item.getIcon() == null) {
						Bitmap scaledBitmap = item.mApiAdapter.getScaledIcon(item.mType, item.mDistanceLevel);
				        item.setIcon(scaledBitmap);
					}
					text = item.mName;
					if (text != null) {
//						if (text.length()>8) {
//							text = text.substring(0, 8);
//							text = text + "...";
//						}
//						text = text + "("+((int)(item.mDistance)) +"m)";
//						if (item.mTextWidth == -1) {
//							item.mTextWidth = (int)mTextPaint.measureText(text);
//						}
						frameRect.left = item.mX - 5;
						frameRect.top = item.mY - 5;
//						frameRect.right = item.mX + item.mIconWidth + item.mTextWidth + 4 + 5;
//						frameRect.bottom = item.mY + item.mIconHeight + 5;
						frameRect.right = item.mX + item.mIconWidth + 4 + 5;
						frameRect.bottom = item.mY + item.mIconHeight + 5;
						if (item.mFrameRect == null) {
							item.mFrameRect = new RectF(frameRect);
						} else {
							item.mFrameRect.left	= frameRect.left;
							item.mFrameRect.top	= frameRect.top;
							item.mFrameRect.right	= frameRect.right;
							item.mFrameRect.bottom	= frameRect.bottom;
						}
//						canvas.drawRoundRect(frameRect, 5, 5, mBasePaint);
//						canvas.drawRoundRect(frameRect, 5, 5, mFramePaint);
//						canvas.drawText(text, item.mX+item.mIconWidth+4, item.mY+item.mIconHeight/2, mTextPaint);
						canvas.drawBitmap(item.getIcon(), item.mX, item.mY, null);
					} else {
						if (item.mFrameRect == null) {
							item.mFrameRect = new RectF(item.mX, item.mY, item.mX+item.mIconWidth, item.mY+item.mIconHeight);
						} else {
							item.mFrameRect.left	= item.mX;
							item.mFrameRect.top	= item.mY;
							item.mFrameRect.right	= item.mX + item.mIconWidth;
							item.mFrameRect.bottom	= item.mY + item.mIconHeight;
						}
						canvas.drawBitmap(item.getIcon(), item.mX, item.mY, null);
					}
				}
			}
		}
	}
}
